<template>
  <div class="root-box">
    <el-form
      class="input-form"
      label-position="right"
      label-width="120px"
      ref="editForm"
      :rules="propRules"
      :disabled="propReadonly"
      :model="form"
    >
      <el-row >
        <el-col class="col-box" :name="item.name" :columnindex="index" :span="getColSpan(item)" v-for="(item,index) in baseColumns" :key="item.name" v-if="'none' != item.inputType && item.inputType != 'dataview' && item.inputType != 'element'">
          <el-form-item   :prop="item.name" :label="getPreviewTitle(item)">
            <!-- 空白提示框-->
            <div  v-if="item.id == -1"  >{{item.name}}</div>

            <!-- 禁用-->
            <div v-else-if="item.inputType == 'disabled'" v-html="form[item.name]"></div>

            <!-- 文本框-->
            <el-input  v-else-if="item.inputType == 'text'" v-model="form[item.name]"  />

            <!-- 文本域-->
            <el-input  v-else-if="item.inputType == 'textarea'" v-model="form[item.name]" type="textarea" :autosize="{ minRows: 1, maxRows: 4}"  />

            <!-- 数值框-->
            <el-input  v-else-if="item.inputType == 'number'" v-model="form[item.name]" />

            <!-- 日期-->
            <el-date-picker v-else-if="item.inputType == 'date'" v-model="form[item.name]"   type="date" :format="dates.defaultDatePattern"
                            :picker-options="dates.pickerOptions.date"/>

            <!-- 下拉框 使用数据字典的-->
            <el-select v-else-if="item.inputType == 'select' && item.dict"  placeholder="请选择"  filterable v-model="form[item.name]" >
              <el-option v-for="dict in item.data?item.data: []" :key="dict.value" :label="dict.label" :value="dict.value"/>
            </el-select>

            <!-- 下拉框 使用数据源的-->
            <el-select v-else-if="item.inputType == 'select' && item.source"  placeholder="请选择"  filterable v-model="form[item.name]" >
              <el-option v-for="dict in item.data?item.data: []" :key="dict.id" :label="dict.name" :value="dict.id"/>
            </el-select>

            <!-- 复选框-->
            <el-checkbox v-else-if="item.inputType == 'checkbox'"  v-model="form[item.name]">{{item.title}}</el-checkbox>

            <!-- 开关-->
            <el-switch
              v-else-if="item.inputType == 'switch'"
              active-color="#13ce66"
              v-model="form[item.name]"
              inactive-color="#ff4949">
            </el-switch>
          </el-form-item>
        </el-col>
      </el-row>
    </el-form>

    <el-row >
      <!-- 数据视图 或者element-->
      <el-col class="col-box" :span="24" >
        <el-tabs v-model="tabActiveName" class="el-tabs-38" >
          <el-tab-pane   :label="getPreviewTitle(item)" :name="item.name" :columnindex="index"  v-for="(item,index) in baseColumns" :key="item.name" v-if="'none' != item.inputType && (item.inputType == 'dataview' || item.inputType == 'element') &&  item.flagTabMain == true">
            <el-row  >
              <el-col :span="getColSpan(item)" style="padding-right: 11px;">
                <small  class="user-msg">{{item.userMsg}}</small>
                <data-view
                  v-if="item.inputType == 'dataview'"
                  :ref="item.name"
                  :id="item.name"

                  :propViewKey="item.dict"
                   propViewForm="frame/data-view/detail-model.vue"
                  :propExtraButtonClickParam="item"
                  :propUserParam="getEval(item.propUserParam, true)"
                  :propPreQueryWrapper="getEval(item.propPreQueryWrapper)"
                  :propSubHeight="getSubHeight()"
                  :propAutoFetchData="item.propAutoFetchData && item.propAutoFetchData == true ? true : false"
                  :propsDisableDbClick="item.propsDisableDbClick && item.propsDisableDbClick == true ? true : false"
                  :propOnlyQuery2="item.propOnlyQuery2 && item.propOnlyQuery2 == true ? true : false"
                  :propHideFlowSelect="item.propHideFlowSelect && item.propHideFlowSelect == true ? true : false"
                  :propPageSize="item.propPageSize ? item.propPageSize : null"

                  @extra-button-click="extraButtonClick"
                  @after-delete="getEvalFun(item2.afterDelete)"

                />

                <div  v-if="item.dict == 'el_tree'"
                      v-loading="item.listLoading"
                      element-loading-text="拼命加载中"
                      element-loading-spinner="spinner-user"
                      element-loading-background="rgba(0, 0, 0, 0)"
                      element-loading-custom-class="spinner-custom"
                >
                  <el-input

                    class="search-input"
                    placeholder="回车搜索"
                    v-model="item.treefilterText"
                    prefix-icon="el-icon-search"
                    @keyup.native.enter="treeFilter(item)"
                    clearable>
                    <template slot="append">
                      <el-button type="primary" class="refresh" @click="loadDatas(item.name)" >刷新</el-button>
                      <el-button type="primary"   @click="setAllExpand(item)"  style="margin-left: 33px">{{item.treeExpand == false ? '展开' : '折叠'}}</el-button>
                      <el-button type="primary" @click="treeSave(item)" style="margin-left: 33px">保存</el-button>
                    </template>
                  </el-input>
                  <el-tree
                    :ref="item.name"
                    :id="item.name"
                    :data="item.data"

                    node-key="id"
                    :props="defaultTreeProps"
                    :show-checkbox="item.showCheckbox && item.showCheckbox == true ? true : false"
                    :default-expand-all="item.defaultExpandAll && item.defaultExpandAll == true ? true : false"

                    :filter-node-method="treeFilterNode"
                    class="mytree"
                    :style="{maxHeight: getTreeMax()}"
                  />
                </div>


              </el-col>
              <el-col :span="getColSpan(item2)" v-for="(item2,index2) in baseColumns" :key="item2.name" v-if="'none' != item2.inputType && (item2.inputType == 'dataview' || item2.inputType == 'element') &&  item2.flagTabMain != true &&  item2.tabPaneIndex == item.tabPaneIndex">
                <small  class="user-msg">{{item2.userMsg}}</small>

                <data-view
                  v-if="item2.inputType == 'dataview'"
                  :ref="item2.name"
                  :id="item2.name"

                  :propViewKey="item2.dict"
                  propViewForm="frame/data-view/detail-model.vue"
                  :propExtraButtonClickParam="item2"
                  :propUserParam="getEval(item2.propUserParam, true)"
                  :propPreQueryWrapper="getEval(item2.propPreQueryWrapper)"
                  :propSubHeight="getSubHeight()"
                  :propAutoFetchData="item2.propAutoFetchData && item2.propAutoFetchData == true ? true : false"
                  :propsDisableDbClick="item2.propsDisableDbClick && item2.propsDisableDbClick == true ? true : false"
                  :propOnlyQuery2="item2.propOnlyQuery2 && item2.propOnlyQuery2 == true ? true : false"
                  :propHideFlowSelect="item2.propHideFlowSelect && item2.propHideFlowSelect == true ? true : false"
                  :propPageSize="item2.propPageSize ? item2.propPageSize : null"

                  @extra-button-click="extraButtonClick"
                  @after-delete="getEvalFun(item2.afterDelete)"

                />

                <div  v-if="item2.dict == 'el_tree'"
                      v-loading="item2.listLoading"
                      element-loading-text="拼命加载中"
                      element-loading-spinner="spinner-user"
                      element-loading-background="rgba(0, 0, 0, 0)"
                      element-loading-custom-class="spinner-custom"
                >
                  <el-input
                    class="search-input"
                    placeholder="回车搜索"
                    v-model="item2.treefilterText"
                    prefix-icon="el-icon-search"
                    @keyup.native.enter="treeFilter(item2)"
                    clearable>
                    <template slot="append">
                      <el-button type="primary" class="refresh" @click="loadDatas(item2.name)" >刷新</el-button>
                      <el-button type="primary"   @click="setAllExpand(item2)"  style="margin-left: 33px">{{item2.treeExpand == false ? '展开' : '折叠'}}</el-button>
                      <el-button type="primary" @click="treeSave(item2)" style="margin-left: 33px">保存</el-button>
                    </template>
                  </el-input>

                  <el-tree
                    :ref="item2.name"
                    :id="item2.name"
                    :data="item2.data"

                    node-key="id"
                    :props="defaultTreeProps"
                    :show-checkbox="item2.showCheckbox && item2.showCheckbox == true ? true : false"
                    :default-expand-all="item2.defaultExpandAll && item2.defaultExpandAll == true ? true : false"
                    :filter-node-method="treeFilterNode"
                    class="mytree"
                    :style="{maxHeight: getTreeMax()}"
                  />
                </div>
              </el-col>
            </el-row>
          </el-tab-pane>
        </el-tabs>
      </el-col>
    </el-row>

  </div>
</template>

<script>
/* eslint-disable*/
export default {
  name: 'detailModel',
  data() {
    return {
      form: {},
      viewData: {},
      baseColumns: [], //基础数据列
      tabActiveName: null,
      defaultTreeProps: {
        children: 'children',
        label: 'label'
      }
    }
  },
  created() {
    this.baseColumns = this.propParent.baseColumns
    console.log('detailModel，baseColumns',this.baseColumns)
    this.tabActiveName = this.baseColumns.filter(item => 'none' != item.inputType && item.inputType == 'dataview' &&  item.flagTabMain == true )[0].name

    this.$emit('event-register', {
      validate: callback => {
        this.$refs.editForm.validate(callback)
      },
      beforeSave: () => {
        this.$emit('data-callback', this.form)
        return true
      },
      afterMove: (formData, initData) => {
        this.form = global.utils.jsonClone(formData)
        this.$set(this.form, 'id', this.form.id)
        this.loadDatas()
      },
      afterSave: () => {
      },
      beforeDelete: () => {
        return true
      },
      afterDelete: () => {},
      beforeFlow: flowButtonKey => {
        return true
      },
      afterFlow: flowButtonKey => {},
      beforeClose: () => {
        return true
      }
    })
  },
  props: {
    propParent: Object,
    propInitData: Object,
    propPrimaryKey: String,
    propDictionaries: Object,
    propCurrentRow: Object,
    propViewFormData: Object,
    propReadonly: Boolean,
    propStatus: String,
    propRules: Object
  },
  methods: {
    //获取列数
    getColSpan(item) {
      return Number(this.utilNum.toFixed(item.colSpan, 0))
    },

    //获取标题
    getPreviewTitle(item) {
      return item.title ? item.title : item.name+ '(未配置显示名称)'
    },

    //初始化数据字典
    loadDatas(nameHit) {
      this.baseColumns.forEach(item => {
        if (!item.dict && !item.source) return true
        if (nameHit && nameHit != item.name) return
        //有数据源的
        if (item.source) {
          this.$set(item,'listLoading', true)

          let params = {}
          if (item.treeDataParam) {
            params = this.getEval(item.treeDataParam, true)
          }
          this.$ajax.get(item.source, {params: params}).then((response) => {
            if(response.code == 0 ){
              //需要进行转换  treeDataConvert
              if (item.treeDataConvert) {
                let fun =  eval('(treeData) => { '+ item.treeDataConvert + '}')
                this.$set(item, 'data', fun(response.data))
                this.$set(item, 'dataOld', item.dataOld)
              } else {
                this.$set(item, 'data', response.data)
              }
              this.$set(item,'listLoading', false)
            }
          })
          return true
        }

        if (item.dict) {
          item.data = this.utils.getDictDataList(item.dict)
          return true
        }
      })
    },

    //格式化js
    getEval(jsEval, byFun, funParam){
      if (byFun == true) {
        let fun =  eval('() => { return '+ jsEval + '}')
        return  fun(funParam)
      }
      return eval(jsEval)
    },

    //格式化js方法，并执行
    getEvalFun(funEval){
      //代码需要包裹一层，不然里面包含return等语句时，会报错
      let fun =  eval('() => { '+ funEval + '}')
      fun()
    },

    //获取树最大高度
    getTreeMax(){
      let max = 400
      try{
        max=$(window).height()-$(this.$refs.editForm.$el).height()  - 90 - 50 - 120
      }catch (e) {
      }
      return max + 'px'
    },

    //表格高度
    getSubHeight() {
      if (!this.$refs || !this.$refs.editForm) return 0
      return $(this.$refs.editForm.$el).outerHeight() + 40
    },

    //扩展事件
    async extraButtonClick(param) {
      //需要先保存主表
      if (!this.form.id && param.extraButtonClickParam.flagSaveForm == true) {
        await this.propParent.ocAsynSaveViewForm()
        if (this.propParent.flagSuccessSave != true) {
          this.utilMessage.warning('表单保存失败，请检查是否有必填项未填写')
          return
        }
      }

      let that = this
      //代码需要包裹一层，不然里面包含return等语句时，会报错
      try {
        let fun =  eval('(param) => { '+ param.extraButtonClickParam.extraButtonClick + '}')
        fun(param)
      }catch (e) {
        console.error('detailModel.extraButtonClick.error')
        console.error('#########js代码#########')
        console.error(param.extraButtonClickParam.extraButtonClick)
        console.error('#########异常原因#########')
        console.error(e)
      }
    },

    //树搜索
    treeFilterNode(value, data) {
      if (!value) return true;
      return data.label.indexOf(value) !== -1;
    },
    //设置全部展开和折叠
    setAllExpand(item){
      this.$set(item,'listLoading', true)
      //树节点过多时候，为了看起来不卡顿，加个延迟
      setTimeout(() => {
        var nodes= this.$refs[item.name][0].store.nodesMap
        if (item.treeExpand == undefined)  this.$set(item, 'treeExpand', true)
        for(var i in nodes){
          nodes[i].expanded= !item.treeExpand
        }
        this.$set(item, 'treeExpand', !item.treeExpand)
        this.$set(item,'listLoading', false)
      }, 500)
    },
    //树搜索
    treeFilter(item) {
      this.$refs[item.name][0].filter(item.treefilterText)
    },
    //树保存
    async treeSave(item) {

      let tree = this.$refs[item.name][0]
      //树选中的
      let nodeIds = []
      let selectedNodes = tree.getCheckedNodes(false, true)
      selectedNodes.forEach(node => {
        /*if (node.meta && node.meta.url && node.meta.url.length > 0) {
          selectedKeyArray.push(node.id)
        }*/
        nodeIds.push(node.id)
      })

      if (item.treeNotAllowSaveIfnull && item.treeNotAllowSaveIfnull == true && nodeIds.length <1) {
        this.utilMessage.warning('未选择任何树节点，不允许提交')
        return
      }
      if (this.strings.isBlank(item.treeSaveUrl)) {
        this.utilMessage.warning('未配置树控件的保存地址，请联系开发人员')
        return
      }

      //需要先保存主表
      if (!this.form.id && item.flagSaveForm == true) {
        await this.propParent.ocAsynSaveViewForm()
        if (this.propParent.flagSuccessSave != true) {
          this.utilMessage.warning('表单保存失败，请检查是否有必填项未填写')
          return
        }
      }

      this.utilVue.loadShow(true)
      let params =  this.form

      //附加参数
      if (item.treeSaveParam) {
        let treeSaveParam = this.getEval(item.treeSaveParam, true)
        Object.keys(treeSaveParam).forEach(key => {
          params[key] = treeSaveParam[key]
        })
      }
      params.nodeIds = nodeIds.join(',')
      this.$ajax.post(item.treeSaveUrl, params).then(resp => {
        this.utilVue.loadHide()
        if ( resp.code == 0 ){
          this.utilMessage.success(resp.msg)
          this.loadDatas(item.name)

          //树保存后执行
          if (item.treeSaveAfter) this.getEvalFun(item.treeSaveAfter)
        }
      })
    }
  }
}
</script>

<style lang="scss" scoped>
  .root-box{
    /deep/ .mytree{
      overflow: auto;
    }
    .user-msg{
      padding-bottom: 9px;
      display: inline-block;
      line-height: 100%;
    }
    .search-input{
      width: 50%;
      padding-bottom: 9px;
    }
  }
</style>
